/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package fjnu.bll;

import fjnu.dao.AbstractObject;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;

/**
 *
 * @author neco
 */
public class Cache {

    private static Cache cake;
    private Queue<AbstractObject> LRU1;
    private Queue<AbstractObject> LRU2;
    private final static int CacheSize = 80;
    

    private Cache() {
        LRU1 = new ConcurrentLinkedQueue<AbstractObject>();
        LRU2 = new ConcurrentLinkedQueue<AbstractObject>();

    }

    private static synchronized void init() {
        if (cake == null) {
            cake = new Cache();
        }
    }

    public static Cache getInstance() {
        init();
        return cake;
    }

    public void addObjectToLRU1(AbstractObject ao) {
        if (ao == null) {
            throw new NullPointerException();
        }
        if (LRU1.contains(ao)) {
            addObjectToLRU2(ao);
        }
        LRU1.offer(ao);
        cleanCache();
    }

    public void addObjectToLRU2(AbstractObject ao) {
        if (ao == null) {
            throw new NullPointerException();
        }
        if (!LRU2.contains(ao)) {
            LRU1.offer(ao);
            cleanCache();
        }
    }

    public AbstractObject getObjectByID(int ID) {
        AbstractObject ao = null;
        for (Object obj : LRU1.toArray()) {
            AbstractObject temp = (AbstractObject) obj;
            if (temp.getID() == ID) {
                LRU1.remove(temp);
                LRU2.offer(temp);
                return temp;
            }
        }
        for (Object obj : LRU2.toArray()) {
            AbstractObject temp = (AbstractObject) obj;
            if (temp.getID() == ID) {
                return temp;
            }
        }
        return ao;
    }
    private void cleanCache() {
        if (LRU2.size()>= CacheSize)
        {
            AbstractObject ao = LRU2.poll();
            ao.deleteMapper();
            ao = null;
        }
        if (LRU1.size() > CacheSize/2)
        {
            AbstractObject ao = LRU1.poll();
            ao.deleteMapper();
            ao = null;
        }
    }
    public static void releaseCache()
    {
        if(cake!=null)
        cake=null;
    }
}
